import { createFileDBStore } from '@/dbStore/fileStore'

interface ICreateTableKey {
  key: string
  unique: boolean
}

interface IStoreOptions {
  keyPath?: string
  autoIncrement?: boolean
}

interface IStoreAdd {
  id: string

  [key: string]: unknown
}

const DBName = 'WOS'
const dbStore = window.indexedDB.open(DBName) as IDBOpenDBRequest
let db: IDBDatabase

dbStore.onupgradeneeded = (ev: IDBVersionChangeEvent) => {
  const target = ev.target as IDBRequest
  db = target.result
  createFileDBStore()
}

dbStore.onsuccess = () => {
  db = dbStore.result
}

/** 创建DB
 * @param tableName 表名称
 * @param keyArr ICreateTableKey
 * @param storeOptions IStoreOptions
 */
export const createDBStore = (
  tableName: string,
  keyArr: ICreateTableKey[],
  storeOptions?: IStoreOptions
): IDBObjectStore => {
  if (!db.objectStoreNames.contains(tableName)) {
    const { keyPath = 'id', autoIncrement = true } = storeOptions || {}
    const objectStore = db.createObjectStore(tableName, { keyPath, autoIncrement })
    keyArr.forEach((item) => {
      objectStore.createIndex(item.key, item.key, { unique: item.unique })
    })
    return objectStore
  }
  return db.transaction(tableName, 'readwrite').objectStore(tableName)
}

/** 添加数据
 * @param tableName
 * @param data
 */
export const addDBStore = async (tableName: string, data: IStoreAdd): Promise<void> => {
  const isHad = await getDBStore(tableName, data.id)
  return new Promise((resolve, reject) => {
    const objectStore = db.transaction(tableName, 'readwrite').objectStore(tableName)
    const request = isHad ? objectStore.put(data) : objectStore.add(data)
    request.onsuccess = () => {
      resolve()
    }
    request.onerror = () => {
      reject(request.error)
    }
  })
}

/** 获取DB数据
 * @param tableName 表名称
 * @param id 表ID
 */
export const getDBStore = <T>(tableName: string, id: string): Promise<T> => {
  return new Promise((resolve, reject) => {
    const request = db.transaction(tableName, 'readonly').objectStore(tableName).get(id)
    request.onsuccess = () => {
      resolve(request.result)
    }
    request.onerror = () => {
      reject(request.error)
    }
  })
}

/** 删除DB数据
 * @param tableName 表名称
 * @param id 表ID
 */
export const deleteDBStore = (tableName: string, id: string): Promise<void> => {
  return new Promise((resolve, reject) => {
    const request = db.transaction(tableName, 'readwrite').objectStore(tableName).delete(id)
    request.onsuccess = () => {
      resolve()
    }
    request.onerror = () => {
      reject(request.error)
    }
  })
}

/** 删库
 * @param tableName 表名称
 */
export const clearDBStore = (tableName: string): Promise<void> => {
  return new Promise((resolve, reject) => {
    const request = db.transaction(tableName, 'readwrite').objectStore(tableName).clear()
    request.onsuccess = () => {
      resolve()
    }
    request.onerror = () => {
      reject(request.error)
    }
  })
}
